﻿using System;
using System.Linq;
using System.Runtime.Serialization;
using Olitee.WorkScheduler.Enumerations;
using Olitee.WorkScheduler.Interfaces;

namespace Olitee.WorkScheduler.Model
{
    /// <summary>
    /// A simple base class implementation of IWorkItem, which provides some boilerplate code to
    /// save you having to implement the full IWorkItem interface.
    /// </summary>
    [DataContract]
    public class WorkItemBase : IWorkItem
    {
        private readonly DateTime timeCreated;
        private readonly Guid id;

        public WorkItemBase()
        {
            id = Guid.NewGuid();
            this.Status = WorkItemStatus.Scheduled;
            this.timeCreated = DateTime.Now;
            this.TimeStarted = DateTime.MinValue;
            this.TimeCompleted = DateTime.MinValue;
        }

        /// <summary>
        /// A unique ID number that identifies this work item.
        /// </summary>
        public Guid Id
        {
            get { return id; }
        }

        /// <summary>
        /// A short string used to pass back messages from the processor (such as success, or error details).
        /// </summary>
        [DataMember]
        public string Message
        {
            get;
            set;
        }

        /// <summary>
        /// The progress of the work item. If progress isn't supported, then this property should return -1;
        /// </summary>
        [DataMember]
        public double Progress
        {
            get;
            set;
        }

        /// <summary>
        /// The time the work item was created.
        /// </summary>
        public DateTime TimeCreated
        {
            get
            {
                return this.timeCreated;
            }
        }

        /// <summary>
        /// The time the work processor began processing the work.
        /// </summary>
        [DataMember]
        public DateTime TimeStarted
        {
            get;
            set;
        }

        /// <summary>
        /// The time the work processor completed the work.
        /// </summary>
        [DataMember]
        public DateTime TimeCompleted
        {
            get;
            set;
        }

        /// <summary>
        /// The current status of the work item
        /// </summary>
        [DataMember]
        public WorkItemStatus Status
        {
            get;
            set;
        }

        /// <summary>
        /// Get the processing time elapsed/total. Returns TimeSpan.Zero if processing has not yet begun.
        /// </summary>
        /// <returns>A TimeSpan object containing the duration.</returns>
        public TimeSpan GetProcessingTime()
        {
            if (this.TimeStarted != DateTime.MinValue && this.TimeCompleted == DateTime.MinValue)
            {
                return DateTime.Now - this.TimeStarted;
            }
            else if (this.TimeStarted != DateTime.MinValue && this.TimeCompleted != DateTime.MinValue)
            {
                return this.TimeCompleted - this.TimeStarted;
            }
            else
            {
                 return TimeSpan.Zero;
            }
        }

        public override string ToString()
        {
            return String.Format("id: {0} | status: {1} | progress: {2:000} %", this.Id, this.Status, this.Progress);
        }
    }
}
